// BluetoothManager.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "BluetoothManager.h"

#include "bthutil.h"
#include "regext.h"
#include "snapi.h"

#define WM_BLUETOOTH_STATE_CHANGED WM_USER

static BOOL BluetoothHardwareIsPresent()
{
	DWORD dwHardwarePresent;
	HRESULT hr = RegistryGetDWORD(SN_BLUETOOTHSTATEHARDWAREPRESENT_ROOT,
		SN_BLUETOOTHSTATEHARDWAREPRESENT_PATH,
		SN_BLUETOOTHSTATEHARDWAREPRESENT_VALUE,
		&dwHardwarePresent);
	
	return (hr == S_OK && (dwHardwarePresent & SN_BLUETOOTHSTATEHARDWAREPRESENT_BITMASK) != 0);
}

INT_PTR CALLBACK BluetoothManagerDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HREGNOTIFY hregNotify;
	HWND hWndCtrl;

    switch (message)
    {
        case WM_INITDIALOG:
            {
				NOTIFICATIONCONDITION condition;
                SHINITDLGINFO shidi;

				// Create a Done button and size it.  
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);

				// Display a message box if bluetooth isn't present on this device...
				if (!BluetoothHardwareIsPresent())
				{
					MessageBox(hDlg, L"This device does not appear to have a bluetooth radio.", L"Warning", MB_OK | MB_ICONEXCLAMATION);
				}

				// Ask the state and notification broker (SNAPI) to send us
				// a WM_BLUETOOTH_STATE_CHANGED window message whenever the
				// bluetooth power state changes.
				condition.ctComparisonType = REG_CT_ANYCHANGE;
				condition.dwMask = SN_BLUETOOTHSTATEPOWERON_BITMASK;
				condition.TargetValue.dw = 0;

				RegistryNotifyWindow(SN_BLUETOOTHSTATEPOWERON_ROOT,
					SN_BLUETOOTHSTATEPOWERON_PATH,
					SN_BLUETOOTHSTATEPOWERON_VALUE,
					hDlg,
					WM_BLUETOOTH_STATE_CHANGED,
					0,
					&condition,
					&hregNotify);

				// Initialise the UI by faking a WM_BLUETOOTH_STATE_CHANGED
				// message immediatly.
				PostMessage(hDlg, WM_BLUETOOTH_STATE_CHANGED, 0,  0);

				// Start a timer for one minute (60000 milliseconds)
				SetTimer(hDlg, 1, 60000, NULL);
            }
            return (INT_PTR)TRUE;

		case WM_BLUETOOTH_STATE_CHANGED:
			{
				// The bluetooth radio state has changed so find out
				// the current state and update the user interface.
				HBITMAP hBitmap;
				WCHAR * pszNewLogEntry;

				DWORD dwMode= BTH_POWER_OFF;
				BthGetMode(&dwMode);

				if (dwMode == BTH_POWER_OFF)
				{
					pszNewLogEntry = L"Bluetooth radio is powered off.\r\n";
					hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_POWER_OFF));
				}
				else
				{
					pszNewLogEntry = L"Bluetooth radio is powered on.\r\n";
					hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_POWER_ON));
				}

				// Add a new log entry
				hWndCtrl = GetDlgItem(hDlg, IDC_EDIT_LOG);
				SendMessage(hWndCtrl, EM_SETSEL, -1, -1);
				SendMessage(hWndCtrl, EM_REPLACESEL, FALSE, (LPARAM)pszNewLogEntry);
				
				// Replace the status bitmap
				hWndCtrl = GetDlgItem(hDlg, IDC_STATUS_BITMAP);
				SendMessage(hWndCtrl, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
			}
			break;

		case WM_TIMER:
			// Clear the log textbox
			SetDlgItemText(hDlg, IDC_EDIT_LOG, L"");

			// Count down for 10 seconds
            for (int i = 10; i > 0; i--)
			{
				WCHAR szBuffer[64];

				swprintf(szBuffer, L"Auto shutdown in %ld seconds...\r\n", i);

				hWndCtrl = GetDlgItem(hDlg, IDC_EDIT_LOG);
				SendMessage(hWndCtrl, EM_SETSEL, -1, -1);
				SendMessage(hWndCtrl, EM_REPLACESEL, FALSE, (LPARAM)szBuffer);

				// Delay 1 second
				Sleep(1000);
			}
	
			// Close the application
			EndDialog(hDlg, IDOK);
			break;

        case WM_COMMAND:		
			switch (LOWORD(wParam))
			{
				case IDC_STATUS_BITMAP:
					if (HIWORD(wParam) == STN_CLICKED)
					{
						// The user has clicked on the status bitmap
						// so toggle the state of the radio
						DWORD dwMode = BTH_POWER_OFF;
						BthGetMode(&dwMode);

						if (dwMode == BTH_POWER_OFF)
							BthSetMode(BTH_CONNECTABLE);
						else
							BthSetMode(BTH_POWER_OFF);
					}
					break;

				case IDC_BUTTON_POWERON:
					BthSetMode(BTH_CONNECTABLE);
					break;

				case IDC_BUTTON_POWEROFF:
					BthSetMode(BTH_POWER_OFF);
					break;

				case IDOK:
		            EndDialog(hDlg, IDOK);
			        return (INT_PTR)TRUE;
            }
            break;

        case WM_CLOSE:
			RegistryCloseNotification(hregNotify);
			hregNotify = NULL;

            EndDialog(hDlg, message);
            return (INT_PTR)TRUE;
    }
    return (INT_PTR)FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
	return DialogBox(hInstance, (LPCTSTR)IDD_BLUETOOTHMANAGER, NULL, BluetoothManagerDialog);
}
